home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / src / subgrp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-17  |  30.6 KB  |  1,418 lines

  1. /*
  2.     ARTemis (Graphic Editor for FM-TOWNS)
  3.     (c) MATSUUCHI Ryosuke 1992,1993
  4.  
  5.     subgrp.c
  6.  
  7.     補助グラフィック関数群
  8.  
  9.  
  10. ★描画
  11. *    void    mist(int x,int y,int xlen,int ylen,int col)
  12.     void    aapset(int x, int y, int col, int gray)    //(x,y):16bit fixed-point
  13. *    void    aaline(int x1,int y1,int x2,int y2,int col,pen_t *pen,int gray)
  14. *    void    do_paint(int x,int y)
  15. *    void    psetWithPen(int x,int y,int col,pen_t *pen,bool conc_sw)
  16. *    void    lineWithPen(int x1,int y1,int x2,int y2,int col,pen_t *pen,
  17.                         bool first)
  18. *    void    inverse(int x,int y,int xlen,int ylen)
  19.  
  20. ★特殊描画
  21.     void    plot_mat3(int x, int y, int mat[3][3])
  22.     void    plot_diffuse(int x, int y)
  23.     void    plot_sharp(int x,int y)
  24.     void    plot_sand(int x,int y)
  25.     void    plot_airbrush_start(void)
  26.     void    plot_airbrush(int x,int y)
  27. *    void    plot_pen_func(int x,int y,pen_t *pen, void (*func)(int x,int y))
  28. *    void    plot_pen_diffuse(int x, int y, pen_t *pen)
  29. *    void    plot_pen_sand(int x,int y, pen_t *pen)
  30. *    void    blot_plot(int x, int y, int color, int branch, int depth)
  31. *    void    blot2_plot(int x0, int y0, int color, int branch, int depth)
  32.  
  33. ★描画アルゴリズム
  34. *    void    do_line(int x1,int y1,int x2,int y2,void func(int x,int y)!)
  35. *    void    do_boxline(int x1,int y1,int x2,int y2,void func(int x,int y)!)
  36. *    void    do_boxfill(int x1,int y1,int x2,int y2,
  37.                        void func(int x1,int x2,int y)!)
  38. *    void    do_ellipse(int x,int y,int rx,int ry,void func(int x,int y)!)
  39. *    void    do_ellipsefill(int x,int y,int rx,int ry,
  40.                            void func(int x1,int x2,int y)!)
  41.  
  42. ★各種コマンド
  43.     void    commandPFline_sub(int cmd)
  44. *    void    commandPFline()
  45. *    void    commandPFPset()
  46. *    void    commandBlot()
  47. *    void    commandDiffuse()
  48. *    void    commandSand()
  49. *    void    commandGoshi()
  50. *    void    commandPaint()
  51. *    void    commandFreeTest()
  52.     void    commandPolygon_sub(void    func()!, bool eachbackup)
  53.             // func : (x1,x2,y) の引数で呼び出される
  54. *    void    commandDiffuseArea()
  55. *    void    commandSharp()
  56. *    void    commandSandArea()
  57. *    void    cmd_polygon()
  58.  
  59. ★文字描画
  60.     void    grp_putchar_sub(char *dest, char *src, bool kanji, int col)
  61.     void    grp_putchar(int x, int y, int c, int col, int style)
  62. *    void    ART_putstr_style(int x, int y, char *str, int col, int style)
  63. *    void    ART_putstr(int x, int y, char *str, int col)
  64. *    void    ARTputstr12(int x,int y, char *str, int forecol, int backcol)
  65.  
  66. ★計算
  67. *    int        mixcol(int col1, int col2, int rate, bool rnd)
  68. *    int        my_rand()
  69.  
  70. */
  71.  
  72.  
  73. // アンチエイリアス描画をするかしないか
  74. #define    NO_AA
  75.  
  76. #include <stdio.h>
  77. #include <egb.h>
  78. #include <stdlib.h>
  79. #include <msdos.cf>
  80. #include <fnt.h>
  81. #include <ctype.h>
  82. #include <memory.h>
  83. #include <limits.h>
  84.  
  85. #include "ge.h"
  86. #include "plt16.h"
  87. #include "math2.h"
  88. #include "decimal.h"
  89. #include "imageman.h"
  90. #include "dispman.h"
  91.  
  92. /*--------------------------------------------------------*/
  93. /*                     網目模様の描画                     */
  94. /*--------------------------------------------------------*/
  95.  
  96.  
  97. void mist(int x,int y,int xlen,int ylen,int col)    // 網目模様の描画
  98. {
  99.     int i;
  100.     for (i=0; i<ylen-xlen; i+=2)
  101.         gline(x,y+i,x+xlen-1,y+xlen-1+i,col,DrawNORMAL);
  102.     for ( ; i<ylen; i+=2)
  103.         gline(x,y+i,x+ylen-1-i,y+ylen-1,col,DrawNORMAL);
  104.     for (i=2; i<xlen-ylen; i+=2)
  105.         gline(x+i,y,x+ylen-1+i,y+ylen-1,col,DrawNORMAL);
  106.     for ( ; i<xlen; i+=2)
  107.         gline(x+i,y,x+xlen-1,y+xlen-1-i,col,DrawNORMAL);
  108. }
  109.  
  110.  
  111. void    inverse(int x,int y,int xlen,int ylen)    // 白黒反転
  112. {
  113.     if(DMgetifonepage())
  114.     {
  115.         grboxfill(x,y,xlen,ylen,menu_plt(White),DrawXOR);
  116.     }
  117.     else
  118.     {
  119.         int white = menu_plt(White), black = menu_plt(Black);
  120.         int i,j;
  121.         for(i=0; i<ylen; i++)
  122.         {
  123.             for(j=0; j<xlen; j++)
  124.             {
  125.                 int c = gpoint(x+j,y+i);
  126.                 if (c==white) gpset(x+j,y+i,black,DrawNORMAL);
  127.                 if (c==black) gpset(x+j,y+i,white,DrawNORMAL);
  128.             }
  129.         }
  130.     }
  131. }
  132.  
  133.  
  134. /*--------------------------------------------------------*/
  135. /*              アンチエイリアシング直線描画              */
  136. /*--------------------------------------------------------*/
  137.  
  138.  
  139. #ifndef NO_AA
  140.  
  141. static void aapset(int x, int y, int col, int gray)
  142. // (x,y) : 16bit fixed-point 座標
  143. {
  144.     x = (x+128)>>8;        // 8bit fixed-point へ変換
  145.     y = (y+128)>>8;
  146.     int x1,x2,y1,y2,h1,h2,v1,v2,a11,a12,a21,a22;
  147.     x1 =  x &  0xffffff00;
  148.     x2 = x1 + 0x100;
  149.     y1 =  y &  0xffffff00;
  150.     y2 = y1 + 0x100;
  151.     h1 = x2 - x;
  152.     h2 = x - x1;
  153.     v1 = y2 - y;
  154.     v2 = y - y1;
  155.     a11 = (h1*v1)>>8;
  156.     a12 = (h1*v2)>>8;
  157.     a21 = (h2*v1)>>8;
  158.     a22 = (h2*v2)>>8;
  159.     x1 >>= 8;
  160.     y1 >>= 8;
  161.     x2 >>= 8;
  162.     y2 >>= 8;
  163.     if (a11 > 0)
  164.     {
  165.         if (a11 >= 256)
  166.             gpset(x1,y1,col,DrawNORMAL);
  167.         else
  168.             EIMgraypset(x1,y1,col,a11);
  169.     }
  170.     if (a21 > 0)
  171.     {
  172.         if (a21 >= 256)
  173.             gpset(x2,y1,col,DrawNORMAL);
  174.         else
  175.             EIMgraypset(x2,y1,col,a21);
  176.     }
  177.     if (a12 > 0)
  178.     {
  179.         if (a12 >= 256)
  180.             gpset(x1,y2,col,DrawNORMAL);
  181.         else
  182.             EIMgraypset(x1,y2,col,a12);
  183.     }
  184.     if (a22 > 0)
  185.     {
  186.         if (a22 >= 256)
  187.             gpset(x2,y2,col,DrawNORMAL);
  188.         else
  189.             EIMgraypset(x2,y2,col,a22);
  190.     }
  191. }
  192.  
  193. #endif
  194.  
  195.  
  196. void aaline(int x1, int y1, int x2, int y2, int col, pen_t *pen, int gray)
  197. {
  198. #ifdef NO_AA
  199.     lineWithPen(x1,y1,x2,y2,col,pen,YES);
  200. #else
  201.     int dx,dy,r;
  202.     dx = _abs(x2-x1);
  203.     dy = _abs(y2-y1);
  204.     if (dx==0 && dy==0)
  205.     {
  206.         gpset(x1,y1,col,DrawNORMAL);
  207.         return;
  208.     }
  209.     if (dx < dy)
  210.     {
  211.         r = (dx << 16) / dy;
  212.         if (y1 > y2)
  213.             { swap(y1,y2);  swap(x1,x2); }
  214.         if (x1 > x2)
  215.             r = -r;
  216.         int iy,ix;
  217.         ix = x1<<16;
  218.         for (iy = y1; iy <= y2; iy++,ix+=r)
  219.             aapset(ix,iy<<16,col,256);
  220.     }
  221.     else
  222.     {
  223.         r = (dy << 16) / dx;
  224.         if (x1 > x2)
  225.             { swap(y1,y2);  swap(x1,x2); }
  226.         if (y1 > y2)
  227.             r = -r;
  228.         int iy,ix;
  229.         iy = y1<<16;
  230.         for (ix = x1; ix <= x2; ix++,iy+=r)
  231.             aapset(ix<<16,iy,col,256);
  232.     }
  233. #endif
  234. }
  235.  
  236.  
  237. /*--------------------------------------------------------*/
  238. /*                    ペイントルーチン                    */
  239. /*--------------------------------------------------------*/
  240.  
  241. typedef struct {
  242.     short int  x,y;
  243.     short int  px1,px2,py;
  244.     bool mark;
  245. } STACK;
  246.  
  247. static STACK *check(int px1,int px2,int py,int sx1,int sx2,int sy,int y,int border, STACK *stack, int stacksize, STACK *sp)
  248. // 新しい sp を返す
  249. {
  250.     int x;
  251.     bool in_border;
  252.     if (y<0 || EIMgetysize()<=y)
  253.         return sp;
  254.     in_border = YES;
  255.     for (x=sx1; x<=sx2; x++) {
  256.         if (in_border) {
  257.             if (EIMpoint(x,y)==border) {
  258.                 if (!(y==py&&px1<=x&&x<=px2) && sp+1 < stack+stacksize) {
  259.                     sp++;
  260.                     sp->x = x;
  261.                     sp->y = y;
  262.                     sp->px1 = sx1;
  263.                     sp->px2 = sx2;
  264.                     sp->py = sy;
  265.                     sp->mark = TRUE;
  266.                 }
  267.                 in_border = NO;
  268.             }
  269.         } else {
  270.             if (EIMpoint(x,y) != border)
  271.                 in_border = YES;
  272.         }
  273.     }
  274.     return sp;
  275. }
  276.  
  277. static void delete(int sx1,int sx2,int sy,STACK *oldsp, STACK *stack, STACK *sp)
  278. {
  279.     STACK *p,*q;
  280.     for (p=stack; p<=oldsp; p++) {
  281.         if (p->y == sy && sx1 <= p->x && p->x <= sx2) {
  282.             p->mark = NO;
  283.             for (q = oldsp+1; q<=sp; q++) {
  284.                 if (q->y == p->py && p->px1 <= q->x && q->x <= p->px2)
  285.                     q->mark = FALSE;
  286.             }
  287.         }
  288.     }
  289. }
  290.  
  291. static void _do_paint(int x,int y,int col)
  292. {
  293.     #define STACKSIZE 600
  294.     STACK stack[STACKSIZE];
  295.     STACK *sp;
  296.  
  297.     STACK *oldsp;
  298.     int sx,sx1,sx2,sy;
  299.     int px1,px2,py;
  300.     int border;
  301.     int mix = getmixrate();
  302.     
  303.     border = EIMpoint(x,y);
  304.     sp = stack;
  305.     sp->x = x;
  306.     sp->y = y;
  307.     sp->px1 = 0;
  308.     sp->px2 = 0;
  309.     sp->py = 0;
  310.     sp->mark = YES;
  311.     while (sp >= stack) {
  312.         if (sp->mark) {
  313.             sx = sp->x;
  314.             sy = sp->y;
  315.             px1 = sp->px1;
  316.             px2 = sp->px2;
  317.             py = sp->py;
  318.             short *ip;
  319.             for (sx1=sx,ip=(short*)EIMadrs(sx1,sy);
  320.                  sx1 > 0 && *(ip-1) == border;
  321.                  sx1--,ip--)
  322.                 ;
  323.             for (sx2=sx,ip=(short*)EIMadrs(sx2,sy);
  324.                  sx2 < EIMgetxsize()-1 && *(ip+1) == border;
  325.                  sx2++,ip++)
  326.                 ;
  327.             EIMgrayhline(sx1,sx2,sy,col,mix,NO);
  328.             oldsp = --sp;
  329.             sp=check(px1,px2,py,sx1,sx2,sy,sy+1,border, stack, STACKSIZE, sp);
  330.             sp=check(px1,px2,py,sx1,sx2,sy,sy-1,border, stack, STACKSIZE, sp);
  331.             delete(sx1,sx2,sy,oldsp, stack,sp);
  332.         } else
  333.             sp--;
  334.     }
  335. }
  336.  
  337. void do_paint(int x,int y)
  338. {
  339.     _do_paint(x,y,forecol);
  340. }
  341.  
  342.  
  343. /*--------------------------------------------------------*/
  344. /*                        混色処理                        */
  345. /*--------------------------------------------------------*/
  346.  
  347.  
  348.     /* 新しいrand()が合わなくなったんで自家製に切り換え 1993 3/6 */
  349. int my_rand()    // by 戸田 浩
  350. {
  351.     static unsigned int next = 1 ;
  352.     next = next * 1103515245 + 12345 ;
  353.     return (unsigned int)( next / 65536 ) % 32768 ;
  354. }
  355.  
  356.  
  357. int mixcol(int col1, int col2, int rate, bool rnd)
  358. // rnd : 乱数によりディザリングするかどうかのスイッチ
  359. {
  360.     short int r1,g1,b1, r2,g2,b2;
  361.     if (rate == 0)
  362.         return col1;
  363.     if (rate == 256)
  364.         return col2;
  365.     r1 = (col1 >> 5) & 31;
  366.     g1 = (col1 >> 10) & 31;
  367.     b1 =  col1 & 31;
  368.     r2 = (col2 >> 5) & 31;
  369.     g2 = (col2 >> 10) & 31;
  370.     b2 =  col2 & 31;
  371.     if (!rnd)
  372.     {
  373.         short int nr = 256-rate;
  374.         r1 = ((r1 * nr + r2 * (short int)rate + 128) >> 8);
  375.         g1 = ((g1 * nr + g2 * (short int)rate + 128) >> 8);
  376.         b1 = ((b1 * nr + b2 * (short int)rate + 128) >> 8);
  377.     }
  378.     else
  379.     {
  380. #define    R    ((short int)my_rand() & 255)
  381.         short int nr = 256-rate;
  382.         r1 = ((r1 * nr + r2 * (short int)rate + R) >> 8);
  383.         g1 = ((g1 * nr + g2 * (short int)rate + R) >> 8);
  384.         b1 = ((b1 * nr + b2 * (short int)rate + R) >> 8);
  385. #undef R
  386.     }
  387.     return (g1 << 10) + (r1 << 5) + b1;
  388. }
  389.  
  390.  
  391. /*--------------------------------------------------------*/
  392. /*                      濃淡付きPSET                      */
  393. /*--------------------------------------------------------*/
  394.  
  395.  
  396. void psetWithPen(int x,int y,int col,pen_t *pen,bool conc_sw)
  397. {
  398.     if (mixrate == 256)
  399.         conc_sw = NO;
  400.     void hdraw(int x0,int y0,int dx,int xlen,int dy, short *graymap)
  401.     {
  402.         EIMgrayhline_map(x0+dx,x0+dx+xlen-1,y0+dy,col,graymap,conc_sw);
  403.     }
  404.     pen_fill(pen, hdraw, x,y,YES);
  405. }
  406.  
  407.  
  408. /*--------------------------------------------------------*/
  409. /*                       ぼかし処理                       */
  410. /*--------------------------------------------------------*/
  411.  
  412.  
  413. static void plot_mat3(int x, int y, int mat[3][3])
  414. {
  415.     if (mode != MODE32K)
  416.         return;
  417.     int max_x, max_y;
  418.     max_x = EIMgetxsize() - 1;
  419.     max_y = EIMgetysize() - 1;
  420.     if (x < 0 || y < 0 || max_x < x || max_y < y)
  421.         return;
  422.     int total[3]; // GRB各要素の強さの合計
  423.     int ix,iy;    // x,y について -1,0,1 と変化する変位
  424.     int ix1,ix2,iy1,iy2;
  425.     total[0] = total[1] = total[2] = 0;
  426.     ix1 = _max(x-1,0    ) - x;
  427.     ix2 = _min(x+1,max_x) - x;
  428.     iy1 = _max(y-1,0    ) - y;
  429.     iy2 = _min(y+1,max_y) - y;
  430.     char *ep0,*ep;  int linsiz;
  431.     ep0 = EIMadrs_back(x+ix1, y+iy1);
  432.     linsiz = EIMgetxbytes();
  433.     for (iy=iy1; iy<=iy2; iy++,ep0+=linsiz)
  434.     {
  435.         ep = ep0;
  436.         for (ix=ix1; ix<=ix2; ix++,ep+=2)
  437.         {
  438.             int c = *(short*)ep;
  439.             int p = mat[iy+1][ix+1];
  440.             total[0] += getG(c) * p;
  441.             total[1] += getR(c) * p;
  442.             total[2] += getB(c) * p;
  443.         }
  444.     }
  445. #define    COL_AVR(a)    ((total[a] + 128) >> 8)
  446.     int t1,t2,t3;
  447.     t1 = _lim(COL_AVR(0),0,31);
  448.     t2 = _lim(COL_AVR(1),0,31);
  449.     t3 = _lim(COL_AVR(2),0,31);
  450.     EIMpset(x, y, GRB(t1,t2,t3), DrawNORMAL);
  451. #undef COL_AVR
  452. }
  453.  
  454.  
  455. static void plot_diffuse(int x, int y)
  456. // 1ドットに対してボカシを実行する
  457. {
  458.     static int mat[3][3] = {{23,23,23},{23,72,23},{23,23,23}};
  459.     plot_mat3(x,y,mat);
  460. }
  461.  
  462.  
  463. static void plot_sharp(int x,int y)
  464. {
  465.     static int mat[3][3] = {{-16,-16,-16},{-16,384,-16},{-16,-16,-16}};
  466.     plot_mat3(x,y,mat);
  467. }
  468.  
  469.  
  470. /*--------------------------------------------------------*/
  471. /*                         砂処理                         */
  472. /*--------------------------------------------------------*/
  473.  
  474.  
  475. static void plot_sand(int x,int y)
  476. {
  477.     int i,c,grb[3];
  478.     c = EIMpoint_back(x,y);
  479.     grb[0]=getG(c), grb[1]=getR(c), grb[2]=getB(c);
  480.     int r;
  481.     r = rand() % 3;
  482.     for (i=0; i<3; i++)
  483.     {
  484.         switch(r)
  485.         {
  486.         case 0:
  487.             if (grb[i] > 0)
  488.                 grb[i]--;
  489.             break;
  490.         case 1:
  491.             if (grb[i] < 31)
  492.                 grb[i]++;
  493.             break;
  494.         }
  495.     }
  496.     c = GRB(grb[0],grb[1],grb[2]);
  497.     EIMpset(x,y,c,DrawNORMAL);
  498. }
  499.  
  500.  
  501. /*--------------------------------------------------------*/
  502. /*             ペン先について任意の処理を行う             */
  503. /*--------------------------------------------------------*/
  504.  
  505.  
  506. static void plot_pen_func(int x, int y, pen_t *pen, void (*func)(int x,int y))
  507. {
  508.     void hline(int x0,int y0,int dx,int xlen,int dy, short *graymap)
  509.     {
  510.         int i;
  511.         for (i=0; i<xlen; i++)
  512.             func(x0+dx+i, y0+dy);
  513.     }
  514.     pen_fill(pen, hline, x,y, YES);
  515. }
  516.  
  517.  
  518. void plot_pen_diffuse(int x, int y, pen_t *pen)
  519. // ペンの形状にあわせた「ボカシ」を実行する
  520. {
  521.     plot_pen_func(x,y,pen,plot_diffuse);
  522. }
  523.  
  524.  
  525. void plot_pen_sand(int x,int y, pen_t *pen)
  526. // ペンの形状にあわせた「ザラザラ化」を実行する
  527. {
  528.     plot_pen_func(x,y,pen,plot_sand);
  529. }
  530.  
  531.  
  532. void lineWithPen(int x1,int y1,int x2,int y2,int col,pen_t *pen,bool first)
  533. // first : 最初の点を描画するかどうか
  534. {
  535.     int xr,yr,r,x,y;
  536.     xr = _abs(x2-x1), yr = _abs(y2-y1);
  537.     if (first)
  538.         psetWithPen(x1,y1,col,pen,YES);
  539.     if (xr==0 && yr==0)
  540.         ;
  541.     else if (xr > yr)
  542.     {
  543.         r = (yr<<16) / xr;
  544.         if (y1 > y2)
  545.             r = -r;
  546.         if (x1 < x2)
  547.         {
  548.             for (x=x1+1,y=(y1<<16)+0x8000+r; x<=x2; x++,y+=r)
  549.                 psetWithPen(x,(y>>16),col,pen,YES);
  550.         }
  551.         else 
  552.         {
  553.             for (x=x1-1,y=(y1<<16)+0x8000+r; x>=x2; x--,y+=r)
  554.                 psetWithPen(x,(y>>16),col,pen,YES);
  555.         }
  556.     }
  557.     else
  558.     {
  559.         r = (xr << 16) / yr;
  560.         if (x1 > x2)
  561.             r = -r;
  562.         if (y1 < y2)
  563.         {
  564.             for (y=y1+1,x=(x1<<16)+0x8000+r; y<=y2; y++,x+=r)
  565.                 psetWithPen((x>>16),y,col,pen,YES);
  566.         }
  567.         else
  568.         {
  569.             for (y=y1-1,x=(x1<<16)+0x8000+r; y>=y2; y--,x+=r)
  570.                 psetWithPen((x>>16),y,col,pen,YES);
  571.         }
  572.     }
  573. }
  574.  
  575.  
  576. /*--------------------------------------------------------*/
  577. /*                  「にじみペン」手続き                  */
  578. /*--------------------------------------------------------*/
  579.  
  580. #define    BLOT_METHOD        1
  581.     // 0=従来どおり(画面上で混色)  1=編集バッファと混色
  582.  
  583. void blot_plot(int x, int y, int color, int branch, int depth)
  584. // 3万色編集時専用。
  585. // branch : 枝分かれする数
  586. // depth : 何回再帰するか
  587. {
  588.     if (mode != MODE32K || depth <= 0)
  589.         return;
  590.     int mixr,mixr0;
  591.     mixr0 = getmixrate();
  592.     int max_x, max_y;
  593.     max_x = EIMgetxsize() - 1;
  594.     max_y = EIMgetysize() - 1;
  595.     void blot_plot_sub(int x, int y, int color, int branch, int depth,
  596.                        deci grad, deci gradsub)
  597.     {
  598.         if (depth <= 0 || grad <= 0 ||
  599.             x < 0 || y < 0 || max_x < x || max_y < y)
  600.         {
  601.             return;
  602.         }
  603.         if (mixr0 == 256)
  604.             EIMgraypset(x,y,color,DeciToInt(grad));
  605.         else
  606.         {
  607.             char *cp;  int conc,t;
  608.             conc = DeciToInt(grad);
  609.             cp = cbuf_adrs(x,y);
  610.             t = cbuf_mix(cbuf2conc(*cp), conc, mixr0);
  611.             *cp = conc2cbuf(t);
  612.             EIMpset(x,y,
  613.                     mixcol(EIMpoint_back(x,y),color,t,NO),
  614.                     DrawNORMAL);
  615.         }
  616.         int b;
  617.         for (b = 0; b < branch; b++)
  618.         {
  619.             int nx,ny;
  620.             nx = x + rand() % 3 - 1;
  621.             ny = y + rand() % 3 - 1;
  622.             blot_plot_sub(nx,ny,color,branch,depth-1,grad-gradsub,gradsub);
  623.         }
  624.     }
  625.     if (mixr0 == 256)
  626.         blot_plot_sub(x,y,color,branch,depth,IntToDeci(50),IntToDeci(50)/depth);
  627.     else
  628.     {
  629.         mixr = mixr0 / 5;
  630.         blot_plot_sub(x,y,color,branch,depth,IntToDeci(mixr),IntToDeci(mixr)/depth);
  631.     }
  632. }
  633.  
  634. /*--------------------------------------------------------*/
  635. /*                   にじみペン part 2                    */
  636. /*--------------------------------------------------------*/
  637.  
  638. void blot2_plot(int x0, int y0, int color, int branch, int depth)
  639. // 3万色編集時専用。
  640. // branch : 枝分かれする数
  641. // depth : 何回再帰するか
  642. {
  643.     static int dxy[][2] = {
  644.         {0,-1},    {1,-1},    {1,0},    {1,1},    {0,1},    {-1,1},    {-1,0},    {-1,-1}
  645.     };
  646.     if (mode != MODE32K || depth <= 0)
  647.         return;
  648.     int mixr,mixr0;
  649.     mixr0 = getmixrate();
  650.     int max_x, max_y;
  651.     max_x = EIMgetxsize() - 1;
  652.     max_y = EIMgetysize() - 1;
  653.     void blot_plot_sub(int x, int y, int color, int branch, int depth,
  654.                        deci grad, deci gradsub, int dir)
  655.     {
  656.         if (depth <= 0 || grad <= 0 ||
  657.             x < 0 || y < 0 || max_x < x || max_y < y)
  658.         {
  659.             return;
  660.         }
  661.         if (mixr0 == 256)
  662.             EIMgraypset(x,y,color,DeciToInt(grad));
  663.         else
  664.         {
  665.             char *cp;  int conc,t;
  666.             conc = DeciToInt(grad);
  667.             cp = cbuf_adrs(x,y);
  668.             t = cbuf_mix(cbuf2conc(*cp), conc, mixr0);
  669.             *cp = conc2cbuf(t);
  670.             EIMpset(x,y,
  671.                     mixcol(EIMpoint_back(x,y),color,t,NO),
  672.                     DrawNORMAL);
  673.         }
  674.         int b;
  675.         for (b = 0; b < branch; b++)
  676.         {
  677.             int d;
  678.             do { d = rand() & 7; } while (d == dir);
  679.             if (dir<0) dir=d;
  680.             blot_plot_sub(x+dxy[d][0],y+dxy[d][1],
  681.                           color, branch, depth-1, grad-gradsub, gradsub, dir);
  682.         }
  683.     }
  684.     if (mixr0 == 256)
  685.         blot_plot_sub(x0,y0,color,branch,depth,IntToDeci(50),IntToDeci(50)/depth,-1);
  686.     else
  687.     {
  688.         mixr = mixr0 / 5;
  689.         blot_plot_sub(x0,y0,color,branch,depth,IntToDeci(mixr),IntToDeci(mixr)/depth,-1);
  690.     }
  691. }
  692.  
  693. // ●エアブラシ
  694.  
  695. // static int ab_r,ab_x,ab_y,ab_c;
  696. static short *airbrush_buf = NULL;
  697.  
  698. static int airbrush_init(void)
  699. {
  700.     if (airbrush_buf != NULL)
  701.         free(airbrush_buf);
  702.     airbrush_buf = calloc(2,(spray_r*2+1)*(spray_r*2+1));
  703.     if (airbrush_buf == NULL)
  704.         return -1;
  705.     int x,y;
  706.     int idx=0;
  707.     if (spray_r > 0)
  708.     {
  709.         for (y=-spray_r; y<=spray_r; y++)
  710.             for(x=-spray_r; x<=spray_r; x++,idx++)
  711.             {
  712.                 deci r = ID(x*x+y*y) / (spray_r*spray_r);
  713.                 if (r<=ID(1))
  714.                 {
  715.                     airbrush_buf[idx] = 32 - DI(32*r);
  716.                 }
  717.             }
  718.     }
  719.     else
  720.         airbrush_buf[0] = 32;
  721.     return 0;
  722. }
  723.  
  724. static void airbrush_end(void)
  725. {
  726.     free(airbrush_buf);
  727.     airbrush_buf = NULL;
  728. }
  729.  
  730. void plot_airbrush_start(void)
  731. {
  732. }
  733.  
  734. void plot_airbrush(int x, int y)
  735. {
  736.     int maxx,maxy;
  737.     maxx = EIMgetxsize()-1;
  738.     maxy = EIMgetysize()-1;
  739.     int x1,y1,x2,y2,xl,x0,y0;
  740.     x1 = _max(0, (x0 = x - spray_r));
  741.     y1 = _max(0, (y0 = y - spray_r));
  742.     x2 = _min(maxx, x + spray_r);
  743.     y2 = _min(maxx, y + spray_r);
  744.     xl = spray_r * 2 + 1;
  745.     int i;
  746.     int idx = xl * (y1-y0) + (x1-x0);
  747.     for (i=y1; i<=y2; i++,idx+=xl)
  748.     {
  749.         EIMgrayhline_map(x1,x2,i,forecol,&airbrush_buf[idx],YES);
  750.     }
  751. }
  752.  
  753. /*--------------------------------------------------------*/
  754. /*                    描画アルゴリズム                    */
  755. /*--------------------------------------------------------*/
  756.  
  757. void do_line(int x1,int y1,int x2,int y2,void func(int x,int y)!)
  758. {
  759.     int xr,yr,r,x,y;
  760.     xr=abs(x2-x1),yr=abs(y2-y1);
  761.     func(x1,y1);    // 最初の点
  762.     if (xr==0 && yr==0)
  763.         ;
  764.     else if (xr > yr)
  765.     {
  766.         r=(yr<<16)/xr; if(y1>y2) r=-r;
  767.         if (x1 < x2)
  768.             for (x=x1+1,y=(y1<<16)+0x8000+r; x<=x2; x++,y+=r)
  769.                 func(x,(y>>16));
  770.         else 
  771.             for (x=x1-1,y=(y1<<16)+0x8000+r; x>=x2; x--,y+=r)
  772.                 func(x,(y>>16));
  773.     }
  774.     else
  775.     {
  776.         r=(xr<<16)/yr; if(x1>x2) r=-r;
  777.         if (y1 < y2)
  778.             for (y=y1+1,x=(x1<<16)+0x8000+r; y<=y2; y++,x+=r)
  779.                 func((x>>16),y);
  780.         else
  781.             for (y=y1-1,x=(x1<<16)+0x8000+r; y>=y2; y--,x+=r)
  782.                 func((x>>16),y);
  783.     }
  784. }
  785.  
  786. void do_boxline(int x1,int y1,int x2,int y2,void func(int x,int y)!)
  787. {
  788.     int i;
  789.     if (x2<x1) swap(x1,x2);
  790.     if (y2<y1) swap(y1,y2);
  791.     for(i=x1;i<=x2;i++) func(i,y1);
  792.     if(y1<y2)
  793.         for(i=x1;i<=x2;i++) func(i,y2);
  794.     for(i=y1+1;i<y2;i++) func(x1,i);
  795.     if(x1<x2)
  796.         for(i=y1+1;i<y2;i++) func(x2,i);
  797. }
  798.  
  799. void do_boxfill(int x1,int y1,int x2,int y2,void func(int x1,int x2,int y)!)
  800. {
  801.     int i;
  802.     if (x2<x1) swap(x1,x2);
  803.     if (y2<y1) swap(y1,y2);
  804.     for(i=y1;i<=y2;i++) func(x1,x2,i);
  805. }
  806.  
  807. void do_ellipse(int x,int y,int rx,int ry,void func(int x,int y)!)
  808. {
  809. #if 0
  810.     #define    ELLIPSE(RX,RY,X0,Y0,X1,Y1)                            \
  811.         {                                                        \
  812.             int x0=RX,s=x0;                                        \
  813.             int y0=0;                                            \
  814.             int px0=-1,py0=-1,px1=-1,py1=-1;                    \
  815.             while(x0>=y0)                                        \
  816.             {                                                    \
  817.                 int x1=x0*RY/RX;                        \
  818.                 int y1=y0*RY/RX;                        \
  819.                 if(px0!=X0||py1!=Y1)                    \
  820.                 {                                                    \
  821.                     func(x+X0,y+Y1);if(X0!=0)func(x-X0,y+Y1);        \
  822.                     if (Y1!=0)                                        \
  823.                      { func(x+X0,y-Y1);if(X0!=0)func(x-X0,y-Y1); }    \
  824.                 }                                                    \
  825.                 if (py0!=Y0||px1!=X1)                                \
  826.                 {                                                \
  827.                     func(x+Y0,y+X1);if(Y0!=0)func(x-Y0,y+X1);        \
  828.                     if (X1!=0)                                        \
  829.                      { func(x+Y0,y-X1);if(Y0!=0)func(x-Y0,y-X1); }    \
  830.                 }                                                \
  831.                 s-=2*y0+1; if(s<0)s+=2*(x0-1),x0--;                \
  832.                 y0++;                                            \
  833.                 px0=X0,py0=Y0,px1=X1,py1=Y1;                    \
  834.             }                                                    \
  835.         }
  836.     #
  837.     if (rx==0 && ry==0)
  838.         func(x,y);
  839.     else if (rx>ry)
  840.         ELLIPSE(rx,ry,x0,y0,x1,y1)
  841.     else
  842.         ELLIPSE(ry,rx,x1,y1,x0,y0)
  843.     #undef ELLIPSE
  844. #endif
  845.     if (rx==0 && ry==0)
  846.         { func(x,y); return; }
  847.     int px,py,prey;
  848.     int a2,b2;
  849.     int c1,c2;
  850.     int e;
  851.     a2=rx*rx,b2=ry*ry;
  852.     px=0,py=ry;
  853.     c1=4*b2,c2=8*a2;
  854.     e=a2*(1-4*ry);
  855.     while(b2*px<=a2*py)
  856.     {
  857.         func(x+px,y+py); if(px!=0)func(x-px,y+py);
  858.         func(x+px,y-py); if(px!=0)func(x-px,y-py);
  859.         prey=py;
  860.         e+=c1*(2*px+1),px++; if(e>0) e-=c2*py,py--;
  861.     }
  862.     px=rx,py=0;
  863.     c1=4*a2,c2=8*b2;
  864.     e=b2*(1-4*rx);
  865.     while(a2*py<=b2*px && py<prey)
  866.     {
  867.         func(x+px,y+py); if(px!=0)func(x-px,y+py);
  868.         if(py!=0) { func(x+px,y-py); if(px!=0)func(x-px,y-py); }
  869.         e+=c1*(2*py+1),py++; if(e>0) e-=c2*px,px--;
  870.     }
  871. }
  872.  
  873. void do_ellipsefill(int x,int y,int rx,int ry,void func(int x1,int x2,int y)!)
  874. {
  875. #if 0
  876.     #define    ELLIPSE(RX,RY,X0,Y0,X1,Y1)                    \
  877.         {                                                \
  878.             int x0=RX,s=x0;                                \
  879.             int y0=0;                                    \
  880.             int py0,py1;                                \
  881.             py0=py1=INT_MIN;                            \
  882.             while(x0>=y0)                                \
  883.             {                                            \
  884.                 int x1=x0*RY/RX;                        \
  885.                 int y1=y0*RY/RX;                        \
  886.                 if (y+Y1 != py0)                        \
  887.                 {                                        \
  888.                     py0=y+Y1;                            \
  889.                     func(x-X0,x+X0,py0);                \
  890.                     func(x-X0,x+X0,y-Y1);                \
  891.                 }                                        \
  892.                 if (y+X1 != py1)                        \
  893.                 {                                        \
  894.                     py1=y+X1;                            \
  895.                     func(x-Y0,x+Y0,py1);                \
  896.                     func(x-Y0,x+Y0,y-X1);                \
  897.                 }                                        \
  898.                 s-=2*y0-1; if(s<0)s+=2*(x0-1),x0--;        \
  899.                 y0++;                                    \
  900.             }                                            \
  901.         }
  902.     #
  903.     if (rx==0&&ry==0)
  904.         func(x,x,y);
  905.     else if (rx>ry)
  906.         ELLIPSE(rx,ry,x0,y0,x1,y1)
  907.     else
  908.         ELLIPSE(ry,rx,x1,y1,x0,y0)
  909.     #undef ELLIPSE
  910. #endif
  911.     if (rx==0 && ry==0)
  912.         { func(x,x,y); return; }
  913.     int px,py,prey;
  914.     int a2,b2;
  915.     int c1,c2;
  916.     int e;
  917.     a2=rx*rx,b2=ry*ry;
  918.     px=0,py=ry;
  919.     c1=4*b2,c2=8*a2;
  920.     e=a2*(1-4*ry);
  921.     prey=-1;
  922.     while(b2*px<=a2*py)
  923.     {
  924.         e+=c1*(2*px+1);
  925.         if(e>0)
  926.         {
  927.             func(x-px,x+px,y+py); func(x-px,x+px,y-py);
  928.             prey=py;
  929.              e-=c2*py,py--;
  930.         }
  931.         px++;
  932.     }
  933.     px=rx,py=0;
  934.     c1=4*a2,c2=8*b2;
  935.     e=b2*(1-4*rx);
  936.     while(a2*py<=b2*px && py<prey)
  937.     {
  938.         func(x-px,x+px,y+py);
  939.         if(py!=0) func(x-px,x+px,y-py);
  940.         e+=c1*(2*py+1),py++; if(e>0) e-=c2*px,px--;
  941.     }
  942. }
  943.  
  944. /*--------------------------------------------------------*/
  945. /*                   「自由線」コマンド                   */
  946. /*--------------------------------------------------------*/
  947.  
  948.  
  949. extern void put_pencol(), get_pencol();
  950.  
  951.  
  952. static void commandPFline_sub(int cmd)
  953. // cmd 0:fline 1:pset
  954. {
  955.     if (cmd == 8)
  956.     {
  957.         if (airbrush_init() != 0)
  958.             return;
  959.     }
  960.     bool drawing;
  961.     int px,py;
  962.     drawing = NO;
  963.     for (;;)
  964.     {
  965.         DMdispcsr(ms.x,ms.y);
  966.         do
  967.         {
  968.             ms_get(&ms);
  969.         } while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
  970.                  key_chk() == 0);
  971.         DMerasecsr();
  972.         scrollForCsr(1,1);
  973.         if (ms.btn2==OFFON)
  974.             break;
  975.         else if (ms.btn1==OFFON)
  976.         {
  977.             EIMbackup();
  978.             drawing = YES;
  979.             px = DMimage_getx(ms.x),  py = DMimage_gety(ms.y);
  980.             switch (cmd)
  981.             {
  982.             case 0:
  983.             case 1:
  984.                 cbuf_clear();
  985.                 psetWithPen(px,py,forecol,getcurpen(),YES);
  986.                 break;
  987.             case 2:
  988.                 cbuf_clear();
  989.                 blot_plot(px,py,forecol,1,blot_depth);
  990.                 break;
  991.             case 3:
  992.                 plot_pen_diffuse(px,py,getcurpen());
  993.                 break;
  994.             case 4:
  995.                 plot_pen_sand(px,py,getcurpen());
  996.                 break;
  997.             case 5:
  998.                 get_pencol(px,py,getcurpen());
  999.                 break;
  1000.             case 6:
  1001.                 do_paint(px,py);
  1002.                 break;
  1003.             case 7:    // freetest
  1004.                 cbuf_clear();
  1005.                 blot2_plot(px,py,forecol,1,blot_depth);
  1006.                 break;
  1007.             case 8:
  1008.                 cbuf_clear();
  1009.                 plot_airbrush_start();
  1010.                 plot_airbrush(px,py);
  1011.                 break;
  1012.             }
  1013.         }
  1014.         else if (ms.btn1==ON)
  1015.         {
  1016.             if (drawing)
  1017.             {
  1018.                 int nx,ny;
  1019.                 nx = DMimage_getx(ms.x),  ny = DMimage_gety(ms.y);
  1020.                 switch (cmd)
  1021.                 {
  1022.                 case 0:
  1023.                     if (px!=nx||py!=ny)
  1024.                     {
  1025.                         if (ryosuke && pen_isdottype(getcurpen()))
  1026.                             aaline(px,py,nx,ny,forecol,getcurpen(),256);
  1027.                         else
  1028.                             lineWithPen(px,py,nx,ny,forecol,getcurpen(),NO);
  1029.                     }
  1030.                     break;
  1031.                 case 1:
  1032.                     if (px!=nx||py!=ny)
  1033.                         psetWithPen(nx,ny,forecol,getcurpen(),YES);
  1034.                     break;
  1035.                 case 2:    // にじみペン
  1036.                     blot_plot(nx,ny,forecol,1,blot_depth);
  1037.                     break;
  1038.                 case 3: // ぼかしペン
  1039.                     if (px!=nx||py!=ny)
  1040.                         plot_pen_diffuse(nx,ny,getcurpen());
  1041.                     break;
  1042.                 case 4: // ザラザラペン
  1043.                     if (px!=nx||py!=ny)
  1044.                         plot_pen_sand(nx,ny,getcurpen());
  1045.                     break;
  1046.                 case 5: // 摩筆
  1047.                     if (px!=nx||py!=ny)
  1048.                         put_pencol(nx,ny,getcurpen());
  1049.                     break;
  1050.                 case 7:    // freetest
  1051.                     blot2_plot(px,py,forecol,1,blot_depth);
  1052.                     break;
  1053.                 case 8:
  1054.                     plot_airbrush(px,py);
  1055.                     break;
  1056.                 }
  1057.                 px=nx;
  1058.                 py=ny;
  1059.             }
  1060.         }
  1061.         else
  1062.             drawing = NO;
  1063.     }
  1064.     if (cmd == 8)
  1065.         airbrush_end();
  1066. }
  1067.  
  1068.  
  1069. void commandPFline()
  1070. {
  1071.     commandPFline_sub(0);
  1072. }
  1073.  
  1074.  
  1075. void commandPFPset()
  1076. {
  1077.     commandPFline_sub(1);
  1078. }
  1079.  
  1080.  
  1081. void commandBlot()
  1082. {
  1083.     commandPFline_sub(2);
  1084. }
  1085.  
  1086.  
  1087. void commandDiffuse()
  1088. {
  1089.     commandPFline_sub(3);
  1090. }
  1091.  
  1092.  
  1093. void commandSand()
  1094. {
  1095.     commandPFline_sub(4);
  1096. }
  1097.  
  1098.  
  1099. void commandGoshi()
  1100. {
  1101.     commandPFline_sub(5);
  1102. }
  1103.  
  1104.  
  1105. void commandPaint()
  1106. {
  1107.     commandPFline_sub(6);
  1108. }
  1109.  
  1110.  
  1111. void commandFreeTest()
  1112. {
  1113.     // commandPFline_sub(7); // blot2
  1114.     commandPFline_sub(8); // air-brush
  1115. }
  1116.  
  1117.  
  1118. static void commandPolygon_sub(void func()!, bool eachbackup)
  1119. // func : (x1,x2,y) の引数で呼び出される
  1120. {
  1121.     bool first = YES;
  1122.     for (;;)
  1123.     {
  1124.         if (area_input(AREA_POLYGON) != 0)
  1125.             break;
  1126.         if (eachbackup)
  1127.             EIMbackup();
  1128.         else
  1129.         {
  1130.             if (first)
  1131.                 EIMbackup();
  1132.             first = NO;
  1133.         }
  1134.         int ax1,ay1,ax2,ay2;
  1135.         area_getboundxy(&ax1,&ay1,&ax2,&ay2);
  1136.         int x,y;
  1137.         for (y=ay1; y<=ay2; y++)
  1138.         {
  1139.             x = ax1 + area_chkxylen(ax1,ax2,y,YES);
  1140.             while (x<=ax2)
  1141.             {
  1142.                 int l;
  1143.                 if ((l = area_chkxylen(x,ax2,y,NO)) == 0)
  1144.                     break;
  1145.                 func(x,x+l-1,y);
  1146.                 x += l + area_chkxylen(x+l,ax2,y,YES);
  1147.             }
  1148.         }
  1149.     }
  1150. }
  1151.  
  1152.  
  1153. void commandDiffuseArea()
  1154. {
  1155.     void diffuse_hline(int x1,int x2,int y)
  1156.     {
  1157.         int i;
  1158.         for (i=x1; i<=x2; i++)
  1159.             plot_diffuse(i,y);
  1160.     }
  1161.     commandPolygon_sub(diffuse_hline,YES);
  1162. }
  1163.  
  1164.  
  1165. void commandSharp()
  1166. {
  1167.     void sharp_hline(int x1,int x2,int y)
  1168.     {
  1169.         int i;
  1170.         for (i=x1; i<=x2; i++)
  1171.             plot_sharp(i,y);
  1172.     }
  1173.     commandPolygon_sub(sharp_hline,NO);
  1174. }
  1175.  
  1176.  
  1177. void commandSandArea()
  1178. {
  1179.     void sand_hline(int x1,int x2,int y)
  1180.     {
  1181.         int i;
  1182.         for (i=x1; i<=x2; i++)
  1183.             plot_sand(i,y);
  1184.     }
  1185.     commandPolygon_sub(sand_hline,YES);
  1186. }
  1187.  
  1188.  
  1189. void cmd_polygon()
  1190. {
  1191.     int mix = getmixrate();
  1192.     void hline(int x1,int x2,int y)
  1193.     {
  1194.         EIMgrayhline(x1,x2,y,forecol,mix,NO);
  1195.     }
  1196.     commandPolygon_sub(hline,YES);
  1197. }
  1198.  
  1199.  
  1200. /*--------------------------------------------------------*/
  1201. /*                        文字表示                        */
  1202. /*--------------------------------------------------------*/
  1203.  
  1204.  
  1205. #if 0
  1206. static void grp_putchar_sub(char *dest, char *src, bool kanji, int col)
  1207. /*
  1208.     1 bit pixel 列を 4 bit pixel 列に変換する
  1209. */
  1210. {
  1211.     int i,j;
  1212.     uint col_a[8];
  1213.     static char bit[] = {128,64,32,16,8,4,2,1};
  1214.     col &= 0xf;
  1215.     for (i=0; i<8; i++)
  1216.         col_a[i] = col << (i*4);
  1217.     if (kanji)
  1218.     {
  1219.         for (i=0; i<16; i++,dest+=8,src+=2)
  1220.         {
  1221.             *(uint*)dest = *(uint*)(dest+4) = 0;
  1222.             for (j=0; j<16; j++)
  1223.                 if (*(src+j/8) & bit[j%8])
  1224.                     *(uint*)(dest+(j/8)*4) |= col_a[j%8];
  1225.         }
  1226.     }
  1227.     else
  1228.     {
  1229.         for (i=0; i<16; i++,dest+=4,src++)
  1230.         {
  1231.             *(uint*)dest = 0;
  1232.             for (j=0; j<8; j++)
  1233.                 if (*src & bit[j])
  1234.                     *(uint*)dest |= col_a[j%8];
  1235.         }
  1236.     }
  1237. }
  1238.  
  1239. static void grp_putchar(int x, int y, int c, int col, int style)
  1240. {
  1241.     char font[16*16/8];
  1242.     para_putBlock par;
  1243.     int xlen,ylen,i;
  1244.     bool kanji;
  1245.     if (c <= 0xff /* 半角文字? */)
  1246.     {
  1247.         kanji = NO;
  1248.         xlen=8, ylen=16;
  1249.         FNT_ankRead(xlen,ylen, c, getds(), font);
  1250.         if (style & FNT_bold)
  1251.         {
  1252.             for (i=0; i<16; i++)
  1253.                 font[i] |= font[i] >> 1;
  1254.         }
  1255.     }
  1256.     else // 全角文字
  1257.     {
  1258.         kanji = YES;
  1259.         xlen=ylen=16;
  1260.         FNT_kanjiRead(xlen,ylen, FNT_sjisToJis(c), getds(), font);
  1261.         if (style & FNT_bold)
  1262.         {
  1263.             for (i=0; i<16; i++)
  1264.             {
  1265.                 unsigned int pat;
  1266.                 pat = (font[i*2] << 8) | font[i*2+1];
  1267.                 pat |= pat >> 1;
  1268.                 font[i*2] = pat >> 8,  font[i*2+1] = pat & 0xff;
  1269.             }
  1270.         }
  1271.     }
  1272.     EGB_writeMode(EGB_work, DrawMATTE);
  1273.     EGB_color(EGB_work,3,0);
  1274. #if 0
  1275.     par.buf = font;
  1276.     par.bufsel = getds();
  1277.     par.x1 = x;
  1278.     par.y1 = y;
  1279.     par.x2 = x + xlen - 1;
  1280.     par.y2 = y + ylen - 1;
  1281.     if (style & FNT_shadow)
  1282.     {
  1283.         EGB_color(EGB_work, 0, Black);
  1284.         par.x1++, par.y1++, par.x2++, par.y2++;
  1285.         EGB_putBlockColor(EGB_work, 0, (char*)&par);
  1286.         par.x1--, par.y1--, par.x2--, par.y2--;
  1287.     }
  1288.     EGB_color(EGB_work, 0, col);
  1289.     EGB_putBlockColor(EGB_work, 0, (char*)&par);
  1290. #else
  1291.     char grpbuf[16*16/2],grpbuf2[16*16/2];
  1292.     grp_putchar_sub(grpbuf,font,kanji,col);
  1293.     if (style & FNT_shadow)
  1294.         grp_putchar_sub(grpbuf2,font,kanji,Black);
  1295.     par.buf = grpbuf;
  1296.     par.bufsel = getds();
  1297.     par.x1 = x;
  1298.     par.y1 = y;
  1299.     par.x2 = x + xlen - 1;
  1300.     par.y2 = y + ylen - 1;
  1301.     if (style & FNT_shadow)
  1302.     {
  1303.         par.buf = grpbuf2;
  1304.         par.x1++, par.y1++, par.x2++, par.y2++;
  1305.         EGB_putBlock(EGB_work, 0, (char*)&par);
  1306.         par.x1--, par.y1--, par.x2--, par.y2--;
  1307.         par.buf = grpbuf;
  1308.     }
  1309.     EGB_putBlock(EGB_work, 0, (char*)&par);
  1310. #endif
  1311. }
  1312.  
  1313. #endif
  1314.  
  1315.  
  1316. void    ART_putstr_style(int x, int y, char *str, int col, int style)
  1317. {
  1318. #if 1
  1319.     EGB_fontStyle(EGB_work, style);
  1320.     EGB_color(EGB_work, 1, Black);
  1321.     grp_putstr(x,y,str,col);
  1322. #else
  1323.     int c;
  1324.     for (;;)
  1325.     {
  1326.         if (*str == 0)
  1327.             break;
  1328.         if (iskanji(*str))
  1329.         {
  1330.             c = *str * 256 + *(str+1);
  1331.             grp_putchar(x,y,c,col,style);
  1332.             str++,str++;
  1333.             x += 16;
  1334.         }
  1335.         else
  1336.         {
  1337.             c = *str;
  1338.             grp_putchar(x,y,c,col,style);
  1339.             str++;
  1340.             x += 8;
  1341.         }
  1342.     }
  1343. #endif
  1344. }
  1345.  
  1346.  
  1347. void    ART_putstr(int x, int y, char *str, int col)
  1348. {
  1349.     ART_putstr_style(x,y,str,col,0);
  1350. }
  1351.  
  1352.  
  1353. void ARTputstr12(int x,int y, char *str, int forecol, int backcol)
  1354. {
  1355.     #define    PUTBITBLOCK(x1,y1,x2,y2,dat) { \
  1356.         char para[16];   DWORD(para)=(unsigned int)dat; WORD(para+4)=getds(); \
  1357.         WORD(para+6)=x1; WORD(para+8)=y1; WORD(para+10)=x2; WORD(para+12)=y2; \
  1358.         EGB_putBlockColor(EGB_work, 0, para); }
  1359.     int ds = getds();
  1360.     char fontbuf[24];
  1361.     EGB_color(EGB_work, 0, forecol);
  1362.     EGB_writeMode(EGB_work, DrawNORMAL);
  1363.     while (*str != 0)
  1364.     {
  1365.         if (*str == '\a')
  1366.         {
  1367.             putpict(x,y,Partemis);
  1368.             while (*str == '\a')  str++;
  1369.             x += 52;
  1370.         }
  1371.         else if (_iskanji(*str))
  1372.         {
  1373.             int ofs, sjis = (*str)*256 + *(str+1), jis;
  1374.             jis = FNT_sjisToJis(sjis);
  1375.             if (_iskanji1(sjis))
  1376.             {
  1377.                 ofs = ( ((jis>>8)-0x21)*94 + (jis&0xff) - 0x21)*24 + 0xc00;
  1378.                 _movedata(font12seg, ofs, ds, (uint)fontbuf, 24);
  1379.             }
  1380.             else    // 第1水準じゃない場合
  1381.             {
  1382.                 char font16buf[32];
  1383.                 FNT_kanjiRead(16,16,jis,ds,font16buf);
  1384.                 memset(fontbuf,0,24);
  1385.                 int di=0;
  1386.                 for (int i=0; i<16; i++)
  1387.                 {
  1388.                     ushort p;
  1389.                     p = ((ushort)font16buf[i*2]<<8) | font16buf[i*2+1];
  1390.                     p =  (p&0xc000) | ((p&0x3c00)<<1) | ((p&0x3c0)<<2) |
  1391.                         ((p&0x3c)<<3) | ((p&0x3)<<4);
  1392.                     fontbuf[di*2]   |= (p>>8) & 0xff;
  1393.                     fontbuf[di*2+1] |= p & 0xff;
  1394.                     if (i!=1 && i!=4 && i!=7 && i!=10)
  1395.                         di++;
  1396.                 }
  1397.             }
  1398.             PUTBITBLOCK(x,y,x+11,y+11,fontbuf);
  1399.             str++,str++;
  1400.             x += 12;
  1401.         }
  1402.         else
  1403.         {
  1404.             if (*str != ' ')
  1405.             {
  1406.                 int ofs = (int)*str * 12;
  1407.                 _movedata(font12seg, ofs, ds, (uint)fontbuf, 12);
  1408.                 PUTBITBLOCK(x,y,x+5,y+11,fontbuf);
  1409.             }
  1410.             str++;
  1411.             x += 6;
  1412.         }
  1413.     }
  1414. }
  1415.  
  1416.  
  1417. /* end of subgrp.c */
  1418.